C++: handle cast arrays properly in off-by-one query#13117
Merged
MathiasVP merged 3 commits intogithub:mainfrom Jun 28, 2023
Merged
C++: handle cast arrays properly in off-by-one query#13117MathiasVP merged 3 commits intogithub:mainfrom
MathiasVP merged 3 commits intogithub:mainfrom
Conversation
geoffw0
previously approved these changes
May 11, 2023
Contributor
geoffw0
left a comment
There was a problem hiding this comment.
LGTM (assuming the two PRs under it get merged first).
| ) { | ||
| pai.getElementSize() = v.getUnspecifiedType().(ArrayType).getBaseType().getSize() and | ||
| v.getUnspecifiedType().(ArrayType).getArraySize() = size and | ||
| v.getUnspecifiedType().(ArrayType).getByteSize() / pai.getElementSize() = size and |
Contributor
There was a problem hiding this comment.
I had to convince myself rounding down here is the right thing to do, by considering some examples.
The pointer size is larger than the array element size:
char buffer[100]; // getByteSize() = 100
int *ptr = (int *)buffer; // pai.getElementSize() will be sizeof(int) = 4 -> size = 25
ptr[24] = ...; // writes bytes 96, 97, 98, 99 - GOOD
ptr[25] = ...; // writes bytes 100, 101, 102, 103 - BAD
The pointer size is smaller than the array element size but does not divide it:
struct vec2 {
int x, y;
}
struct vec3 {
int x, y, z;
}
vec3 array[3]; // getByteSize() = 9 * sizeof(int)
vec2 *ptr = (vec2 *)array; // pai.getElementSize() will be 2 * sizeof(int) -> size = 4
ptr[3] = ... // writes ints 6, 7 - OK
ptr[4] = ... // writes ints 8, 9 - BAD
The pointer size is larger than the array element size and does not divide it:
vec2 array[2]; // getByteSize() = 4 * sizeof(int)
vec3 *ptr = (vec3 *)array; // pai.getElementSize() will be 3 * sizeof(int) -> size = 1
ptr[0] = ... // writes ints 0, 1, 2 - OK
ptr[1] = ... // writes ints 3, 4, 5 - BAD
(my examples are untested, may be naive about struct padding)
Contributor
There was a problem hiding this comment.
Thanks for those excellent testcases, Geoffrey! I've added them in 51176bd. It looks like we get the first two cases correct, but miss the last one. I haven't quite figured out why yet.
2b40498 to
0a7ab85
Compare
0a7ab85 to
d18fb64
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Previously, pointer arithmetic done using a different size than the original array were excluded in the constant size off-by-one query. This PR handles that case by using the byte length of the array and dividing by the element size at the pointer arithmetic.
This PR follows #13045 and #13116. Only
2b40498is new.